#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AIOT智能学习桌项目 - Python仿真程序
模拟EBP3901开发板上的所有功能
"""

import time
import random
import threading
import json
from datetime import datetime
from collections import defaultdict

class SimulatedHardware:
    """模拟硬件组件"""
    
    def __init__(self):
        self.led_state = {"red": False, "green": False, "blue": False}
        self.buzzer_active = False
        self.oled_display = ""
        self.distance_sensor = 35.0  # 初始距离35cm
        self.audio_recording = False
        self.audio_playing = False
        
    def read_ultrasonic_distance(self):
        """模拟超声波距离读取"""
        # 模拟距离变化（20-60cm范围）
        variation = random.uniform(-2.0, 2.0)
        self.distance_sensor = max(20.0, min(60.0, self.distance_sensor + variation))
        return self.distance_sensor
        
    def set_led(self, color, state):
        """设置LED状态"""
        self.led_state[color] = state
        
    def buzzer_beep(self, times, duration_ms):
        """蜂鸣器响铃"""
        self.buzzer_active = True
        # 模拟蜂鸣器响铃
        for i in range(times):
            time.sleep(duration_ms / 1000.0)
        self.buzzer_active = False
        
    def oled_display_text(self, text):
        """OLED显示文本"""
        self.oled_display = text
        
    def start_audio_recording(self):
        """开始音频录制"""
        self.audio_recording = True
        
    def stop_audio_recording(self):
        """停止音频录制"""
        self.audio_recording = False
        return "模拟音频数据"
        
    def play_audio(self, text):
        """播放音频"""
        self.audio_playing = True
        time.sleep(1.0)  # 模拟播放时间
        self.audio_playing = False

class VoiceInteractionModule:
    """语音交互模块"""
    
    def __init__(self, hardware):
        self.hardware = hardware
        self.wake_word = "小助手"
        self.conversation_history = []
        self.wake_word_detected = False
        
    def detect_wake_word(self, audio_data):
        """检测唤醒词"""
        # 模拟唤醒词检测（随机触发）
        if random.random() < 0.1:  # 10%概率检测到唤醒词
            self.wake_word_detected = True
            return True
        return False
        
    def process_speech(self, audio_data):
        """处理语音输入"""
        # 模拟语音识别结果
        questions = [
            "今天天气怎么样？",
            "帮我解释一下光合作用",
            "什么是人工智能？",
            "如何保持良好的坐姿？",
            "推荐一些学习方法"
        ]
        return random.choice(questions)
        
    def generate_response(self, question):
        """生成AI回答"""
        responses = {
            "今天天气怎么样？": "今天天气晴朗，适合学习！记得保持良好坐姿哦。",
            "帮我解释一下光合作用": "光合作用是植物利用阳光、水和二氧化碳制造养分的过程。",
            "什么是人工智能？": "人工智能是让计算机模拟人类智能行为的技术。",
            "如何保持良好的坐姿？": "保持背部挺直，双脚平放地面，眼睛距离屏幕50-70厘米。",
            "推荐一些学习方法": "建议使用番茄工作法，每25分钟休息5分钟，保持专注。"
        }
        return responses.get(question, "这是一个很好的问题，让我想想...")
        
    def text_to_speech(self, text):
        """文本转语音"""
        print(f"🔊 语音播放: {text}")
        self.hardware.play_audio(text)

class PostureMonitoringModule:
    """坐姿监测模块"""
    
    def __init__(self, hardware):
        self.hardware = hardware
        self.optimal_distance_min = 30.0  # 最佳距离下限
        self.optimal_distance_max = 50.0  # 最佳距离上限
        self.warning_threshold = 25.0     # 警告阈值
        self.alert_count = 0
        self.monitoring_active = True
        
    def monitor_distance(self):
        """监测坐姿距离"""
        distance = self.hardware.read_ultrasonic_distance()
        
        if distance < self.warning_threshold:
            self.trigger_alert("坐姿过近", distance)
            return "TOO_CLOSE"
        elif distance > self.optimal_distance_max:
            self.trigger_alert("坐姿过远", distance)
            return "TOO_FAR"
        elif self.optimal_distance_min <= distance <= self.optimal_distance_max:
            self.hardware.set_led("green", True)
            self.hardware.set_led("red", False)
            return "OPTIMAL"
        
        return "NORMAL"
        
    def trigger_alert(self, alert_type, distance):
        """触发坐姿警报"""
        self.alert_count += 1
        
        # LED警报
        self.hardware.set_led("red", True)
        self.hardware.set_led("green", False)
        
        # 蜂鸣器警报
        threading.Thread(target=self.hardware.buzzer_beep, args=(3, 200)).start()
        
        # OLED显示
        message = f"{alert_type}: {distance:.1f}cm"
        self.hardware.oled_display_text(message)
        
        # 语音提示
        if alert_type == "坐姿过近":
            speech_text = "请调整坐姿，距离过近可能影响视力健康"
        else:
            speech_text = "请调整坐姿，保持合适的学习距离"
            
        print(f"⚠️  坐姿警报: {message}")
        print(f"🔊 语音提示: {speech_text}")

class DataRecordingModule:
    """数据记录模块"""
    
    def __init__(self):
        self.session_data = {
            "start_time": datetime.now(),
            "study_duration": 0,
            "posture_alerts": 0,
            "distance_readings": [],
            "voice_interactions": 0,
            "avg_distance": 0.0,
            "focus_score": 0.0
        }
        self.daily_records = []
        
    def record_distance(self, distance):
        """记录距离数据"""
        self.session_data["distance_readings"].append({
            "timestamp": datetime.now(),
            "distance": distance
        })
        
    def record_posture_alert(self):
        """记录坐姿警报"""
        self.session_data["posture_alerts"] += 1
        
    def record_voice_interaction(self):
        """记录语音交互"""
        self.session_data["voice_interactions"] += 1
        
    def calculate_session_stats(self):
        """计算会话统计"""
        if self.session_data["distance_readings"]:
            distances = [r["distance"] for r in self.session_data["distance_readings"]]
            self.session_data["avg_distance"] = sum(distances) / len(distances)
            
        # 计算专注度评分（基于坐姿警报频率）
        study_minutes = self.session_data["study_duration"] / 60.0
        if study_minutes > 0:
            alert_rate = self.session_data["posture_alerts"] / study_minutes
            self.session_data["focus_score"] = max(0, 100 - alert_rate * 10)
        
        return self.session_data
        
    def generate_report(self):
        """生成学习报告"""
        stats = self.calculate_session_stats()
        
        report = f"""
📊 学习会话报告
================
⏱️  学习时长: {stats['study_duration']//60:.0f}分{stats['study_duration']%60:.0f}秒
📏 平均距离: {stats['avg_distance']:.1f}cm
⚠️  坐姿提醒: {stats['posture_alerts']}次
🗣️  语音交互: {stats['voice_interactions']}次
🎯 专注度评分: {stats['focus_score']:.1f}/100

💡 建议:
"""
        
        if stats['focus_score'] >= 80:
            report += "- 保持良好的学习状态！\n"
        elif stats['focus_score'] >= 60:
            report += "- 注意保持正确坐姿，减少分心\n"
        else:
            report += "- 建议调整学习环境，提高专注度\n"
            
        if stats['avg_distance'] < 30:
            report += "- 适当增加与桌面的距离\n"
        elif stats['avg_distance'] > 50:
            report += "- 可以稍微靠近一些，保持合适距离\n"
            
        return report

class SmartDeskSimulator:
    """智能学习桌主系统"""
    
    def __init__(self):
        self.hardware = SimulatedHardware()
        self.voice_module = VoiceInteractionModule(self.hardware)
        self.posture_module = PostureMonitoringModule(self.hardware)
        self.data_module = DataRecordingModule()
        
        self.system_running = False
        self.monitoring_thread = None
        self.voice_thread = None
        
    def start_system(self):
        """启动系统"""
        print("🚀 AIOT智能学习桌系统启动中...")
        self.system_running = True
        
        # 初始化显示
        self.hardware.oled_display_text("系统已启动")
        self.hardware.set_led("blue", True)
        
        # 启动监测线程
        self.monitoring_thread = threading.Thread(target=self.monitoring_loop)
        self.monitoring_thread.daemon = True
        self.monitoring_thread.start()
        
        # 启动语音处理线程
        self.voice_thread = threading.Thread(target=self.voice_loop)
        self.voice_thread.daemon = True
        self.voice_thread.start()
        
        print("✅ 系统启动完成！")
        print("📱 功能说明:")
        print("   - 自动监测坐姿距离")
        print("   - 语音交互功能")
        print("   - 数据记录与分析")
        print("   - 按 Ctrl+C 退出系统")
        
    def monitoring_loop(self):
        """监测循环"""
        while self.system_running:
            try:
                # 坐姿监测
                posture_status = self.posture_module.monitor_distance()
                distance = self.hardware.distance_sensor
                
                # 记录数据
                self.data_module.record_distance(distance)
                if posture_status in ["TOO_CLOSE", "TOO_FAR"]:
                    self.data_module.record_posture_alert()
                
                # 更新学习时长
                self.data_module.session_data["study_duration"] += 1
                
                # 显示状态
                status_display = f"距离:{distance:.1f}cm 状态:{posture_status}"
                self.hardware.oled_display_text(status_display)
                
                time.sleep(1.0)  # 每秒检测一次
                
            except Exception as e:
                print(f"❌ 监测循环错误: {e}")
                
    def voice_loop(self):
        """语音处理循环"""
        while self.system_running:
            try:
                # 模拟音频录制
                if random.random() < 0.05:  # 5%概率触发语音事件
                    audio_data = "模拟音频数据"
                    
                    # 检测唤醒词
                    if self.voice_module.detect_wake_word(audio_data):
                        print("🎤 检测到唤醒词: 小助手")
                        self.hardware.set_led("blue", True)
                        
                        # 处理语音输入
                        time.sleep(0.5)  # 模拟处理时间
                        question = self.voice_module.process_speech(audio_data)
                        print(f"👤 用户问题: {question}")
                        
                        # 生成回答
                        response = self.voice_module.generate_response(question)
                        self.voice_module.text_to_speech(response)
                        
                        # 记录交互
                        self.data_module.record_voice_interaction()
                        
                        self.hardware.set_led("blue", False)
                        
                time.sleep(2.0)  # 每2秒检测一次
                
            except Exception as e:
                print(f"❌ 语音处理错误: {e}")
                
    def stop_system(self):
        """停止系统"""
        print("\n🛑 系统正在关闭...")
        self.system_running = False
        
        # 关闭所有LED
        for color in self.hardware.led_state:
            self.hardware.set_led(color, False)
            
        # 显示关闭信息
        self.hardware.oled_display_text("系统已关闭")
        
        # 生成最终报告
        report = self.data_module.generate_report()
        print(report)
        
        print("👋 感谢使用AIOT智能学习桌！")
        
    def display_status(self):
        """显示系统状态"""
        print("\n" + "="*50)
        print("📊 系统实时状态")
        print("="*50)
        print(f"🔴 红色LED: {'开' if self.hardware.led_state['red'] else '关'}")
        print(f"🟢 绿色LED: {'开' if self.hardware.led_state['green'] else '关'}")
        print(f"🔵 蓝色LED: {'开' if self.hardware.led_state['blue'] else '关'}")
        print(f"🔊 蜂鸣器: {'响铃' if self.hardware.buzzer_active else '静音'}")
        print(f"📱 OLED显示: {self.hardware.oled_display}")
        print(f"📏 当前距离: {self.hardware.distance_sensor:.1f}cm")
        print(f"🎤 录音状态: {'录音中' if self.hardware.audio_recording else '待机'}")
        print(f"🔊 播放状态: {'播放中' if self.hardware.audio_playing else '静音'}")
        
        # 显示统计数据
        stats = self.data_module.calculate_session_stats()
        print(f"\n📈 会话统计:")
        print(f"   学习时长: {stats['study_duration']//60:.0f}分{stats['study_duration']%60:.0f}秒")
        print(f"   坐姿提醒: {stats['posture_alerts']}次")
        print(f"   语音交互: {stats['voice_interactions']}次")
        print(f"   专注度: {stats['focus_score']:.1f}/100")

def main():
    """主函数"""
    print("🎯 AIOT智能学习桌项目 - 仿真测试程序")
    print("="*60)
    
    # 创建仿真器实例
    simulator = SmartDeskSimulator()
    
    try:
        # 启动系统
        simulator.start_system()
        
        # 主循环
        while True:
            time.sleep(5.0)  # 每5秒显示一次状态
            simulator.display_status()
            
    except KeyboardInterrupt:
        # 用户按Ctrl+C退出
        simulator.stop_system()
        
    except Exception as e:
        print(f"❌ 系统错误: {e}")
        simulator.stop_system()

if __name__ == "__main__":
    main() 